const koaRouter = require('koa-router');
const Sequelize = require('sequelize');
const md5 = require('md5');

// jwt 测试
const jwt = require('jsonwebtoken')
const secret = 'jwt demo'
const jwtKoa = require('koa-jwt')
const util = require('util')
const verify = util.promisify(jwt.verify) // 解密


const router = new koaRouter();

// models/index 是sequelize init的时候自动创建的 他已经帮我们封装好了数据库的连接，和模型数据等
// 并把所有的模型挂在的db上然后直接导出， 所以可以直接通过 models.Contents访问到 contents数据模型
const models = require('../models/index')

// 首页返回所有的信息
router.get('/list',async (ctx, next) => {

    // 根据参数处理分页信息
    let {currentPage,pageSize} = ctx.query;
    let offset = (currentPage-1)*pageSize; // 偏移量

    // 把所有信息，和关联的用户一起返回
    let rs = await models.Contents.findAndCountAll({
        limit:Number(pageSize), // 注意这里是数字，不能是字符串
        offset:Number(offset), // 注意这里是数字，不能是字符串
        include: {
            model: models.Users
        }
    }).catch((err) => { // 这里只处理服务器连接错误
        console.log('list-------->这里报错了', err.parent)
        return err;
    })


    if(rs.rows){
        // 过滤用户信息中，不返回密码的关键信息
        let datas = rs.rows.map( data => {

            // 这里的data并非json ， 而是sequelize的模型对象
            /*try {
                console.log('data-->', typeof JSON.parse(data))
            }catch (e) {
                console.log('error 1')
            }*/

            return {
                id:data.id,
                title: data.title,
                content: data.content,
                like_count: data.like_count,
                comment_count: data.comment_count,
                user_id: data.user_id,
                createdAt: data.createdAt,
                username: data.User.username,
            }
        })

        ctx.body = {
            code:0,
            data: datas,
            count: rs.count
        };
    }else{ // 报错
        if(rs.parent.code === 'ECONNREFUSED'){
            ctx.body = {
                code:10500,
                msg: '服务器连接错误'
            };

            // 或者试试这个抛错
            // ctx.throw(500, '服务器错误')
        }
    }
})

// 登录， 登录成功，直接保存userid 到cookie里面，    cookie可以替换成 jwt方式 用到 koa-jwt模块,    或者用koa-seesion 加密解密传输
router.post('/login', async (ctx, next) => {
    let {username,password} = ctx.request.body;

    let user = await models.Users.findOne({
        where: {
            username: username
        }
    })

    if(user){
        password = md5(password)

        if (username === user.get('username') && password === user.get('password')) {
            // 登录成功保存uid到cookie 参考：https://koa.bootcss.com/ , 不暴露uid，因为会根据uid 进行点赞，所以对uid进行koa-session加密
            // ctx.cookies.set('uid', user.id, {
            //     httpOnly: true,
            //     maxAge: 1000000   // 1w毫秒存活时间  不建议设置过期时间expires
            // });
            //
            ctx.cookies.set('username', user.username, {
                httpOnly: false,
                signed: false,
                maxAge: 1000000   // 1w毫秒存活时间  不建议设置过期时间expires
            });

            // 结合app.keys 和koa-session设置session， 后面的请求都会带上改session，session其实建立在cookie上的，所有都会带上加密的cookie
            ctx.session.uid = user.id;

            // 生成token
            let token = jwt.sign({uid: user.id}, secret, {expiresIn: '1h'})  //token签名 有效期为1小时

            return ctx.body = {
                code : 0,
                data: user.id,  // 登录成功，返回uid
                token: token,
                msg: '登录成功'
            }
        } else {
            return ctx.body = {
                code : 10002,
                msg: '用户名或密码错误'
            }
        }
    }else{
        return ctx.body = {
            code : 10001,
            msg: '用户不存在'
        }
    }
})


// 退出登录
router.post('/loginout', async (ctx, next) => {
    // 清空cookie
    ctx.cookies.set('koa:message','')

    ctx.body = {
        code : 0,
        msg: '退出登录成功'
    }
})

// 注册
router.post('/register', async (ctx, next) => {
    let {username,password,repassword} = ctx.request.body;
    if(username.trim() === '' || password.trim() === '' || repassword.trim() === ''){
        return ctx.body = {
            code : 10002,
            msg: '用户名或者密码不能为空'
        }
    }else if(password.trim() !== '' && password.trim() !== repassword.trim()){
        return ctx.body = {
            code : 10002,
            msg: '两次密码不一致'
        }
    }else{ // 不做太多的验证
        let user =await models.Users.findOne({
            where:{
                username:username
            }
        })

        if(username === user.username){
            return ctx.body = {
                code : 10003,
                msg: '用户已经存在'
            }
        }else{
            await models.Users.build({
                username: username,
                password: md5(password)
            }).save().then( user => {
                console.log('chenggong  user',  user)

                let addUser = {
                    id: user.id,
                    username: user.username
                }

                return ctx.body = {
                    code : 0,
                    data: addUser,
                    msg: 'ok'
                }
            }).catch((err) => {
                console.log('注册失败--->', err)
            })
        }
    }
})

// 点赞
router.post('/like', async (ctx, next) => {
    let content_id = ctx.request.body.content_id;

    // 方式1 通过uid加密判断登录态
    // koa-session 会对app.keys 加密的cookie自动解密
    let uid = ctx.session.uid;
    if(!uid){
        return ctx.body = {
            code: 10002,
            msg: '未登录'
        }
    }


    // 方式2 通过jwt token判断登录态
    let token = ctx.header.authorization  // 获取jwt
    if(!token){
        return ctx.body = {
            code: 10002,
            msg: '未登录'
        }
    }

    // 打印查看 解密token
    console.log('token ------->', token)

    let payload = await verify(token.split(' ')[1], secret)
    console.log('payload ------->', payload)

    // 首先判断该内容是否存在
    let content = await models.Contents.findById(content_id).catch((err) => {
        console.log('err 点赞', err)
    })
    if(!content){
        return ctx.body = {
            code: 10002,
            msg: '没有对应的内容'
        }
    }


    // 防止重复点赞
    let like = await models.Likes.findOne({
        where:{
            [Sequelize.Op.and]: [
                {'content_id': content_id},
                {'user_id': uid},
            ]
        }
    }).catch((err) => {
        console.log('err 点赞', err)
    });

    if(like){
        return ctx.body = {
            code: 10002,
            msg: '您已经点赞了'
        }
    }


    // 点赞成功，对数据库数据进行追加
    await content.set('like_count', content.like_count + 1).save();
    // await content.save()

    await models.Likes.build({
        content_id:content_id,
        user_id:uid
    }).save();

    ctx.body = {
        code: 0,
        data: content,
        msg: 'ok'
    }

})



module.exports = router;